package com.wss.lsl.test.driven.part1;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 模版解析类
 * 
 * @author sean
 * 
 */
public class TemplateParse {

	/**
	 * 将模版文本解析成纯文本与变量的变量列表
	 * 
	 * @param templateText
	 *            模版文本
	 * @return
	 */
	private List<String> parse(String templateText) {
		List<String> segments = new ArrayList<String>();
		int index = collectSegments(segments, templateText);
		addTail(segments, templateText, index);
		addEmptyStringIfTemplateWasEmpty(segments);

		return segments;
	}

	/**
	 * 将模版文本解析成片段
	 * 
	 * @param templateText
	 * @return
	 */
	public List<Segment> parseSegments(String templateText) {
		List<String> strings = parse(templateText);
		List<Segment> segments = new ArrayList<Segment>();
		for (String string : strings) {
			if (isVariable(string)) {
				String name = string.substring(2, string.length() - 1);
				segments.add(new Variable(name));
			} else {
				segments.add(new PlainText(string));
			}
		}

		return segments;
	}

	/**
	 * 空模版就添加一个空串
	 * 
	 * @param segments
	 */
	private void addEmptyStringIfTemplateWasEmpty(List<String> segments) {
		if (segments.size() == 0) {
			segments.add("");
		}
	}

	/**
	 * 添加模版末尾的纯文本
	 * 
	 * @param segments
	 * @param templateText
	 * @param index
	 */
	private void addTail(List<String> segments, String templateText, int index) {
		if (index < templateText.length()) {
			segments.add(templateText.substring(index));
		}
	}

	/**
	 * 根据正则表达式在模版中提取片段
	 * 
	 * @param segments
	 * @param templateText
	 * @return
	 */
	private int collectSegments(List<String> segments, String templateText) {
		Pattern pattern = Pattern.compile("\\$\\{[^}]*\\}");
		Matcher matcher = pattern.matcher(templateText);
		int index = 0;
		while (matcher.find()) {
			addProcedingPlainText(segments, templateText, matcher, index);
			addVariable(segments, templateText, matcher);
			index = matcher.end();
		}
		return index;
	}

	/**
	 * 添加变量
	 * 
	 * @param segments
	 * @param templateText
	 * @param matcher
	 */
	private void addVariable(List<String> segments, String templateText,
			Matcher matcher) {
		segments.add(templateText.substring(matcher.start(), matcher.end()));
	}

	/**
	 * 添加处理后的纯文本片段
	 * 
	 * @param segments
	 * @param templateText
	 * @param matcher
	 * @param index
	 */
	private void addProcedingPlainText(List<String> segments,
			String templateText, Matcher matcher, int index) {
		if (index != matcher.start()) {
			segments.add(templateText.substring(index, matcher.start()));
		}
	}

	private boolean isVariable(String segment) {
		return segment.startsWith("${") && segment.endsWith("}");
	}

}
